home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Source Code
/
Visual Basic Source Code.iso
/
vbsource
/
metkit
/
myio.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-07
|
5KB
|
169 lines
// Copyright (C) 1996, 1997 Meta Four Software. All rights reserved.
//
// This code demonstrates:
//
// - A class derived from c4_Strategy to implement encrypted storage.
// - Disabling the Flush calls issued during Commit() for speed.
// - Using c4_Strategy objects as the basis of all file I/O in MetaKit.
//
//! rev="$Id: myio.cpp,v 1.6 1997/05/27 00:06:46 jcw Rel $"
#include "m4kit.h"
#include "k4strat.h"
#include <stdio.h>
#include <string.h>
#ifdef macintosh
#include <assert.h>
#define ASSERT assert
#endif
/////////////////////////////////////////////////////////////////////////////
// A helper class which owns a temporary buffer
class CTempBuffer
{
public:
CTempBuffer (int len_) : _buf (new char [len_]) { }
~CTempBuffer () { delete [] _buf; }
operator void* () const { return _buf; }
char& operator[] (int i) { return _buf[i]; }
private:
char* _buf;
};
/////////////////////////////////////////////////////////////////////////////
// This derived strategy encrypts its data on disk and omits flushes
class CEncryptStrategy : public c4_Strategy
{
public:
CEncryptStrategy ()
: _pos (0) { }
virtual ~CEncryptStrategy ()
{ /* nothing */ }
// Need to track the file position to implement better encryption
virtual void DataSeek(long lOff)
{ _pos = lOff; c4_Strategy::DataSeek(lOff); }
// Reading and writing of course messes around with all the data
virtual int DataRead(void*, int);
virtual void DataWrite(const void*, int);
// For this example, we also disable all explicit file flushes
virtual void DataCommit(long)
{ }
private:
// This example uses a trivial encoding. The important aspect to
// consider is to make sure that seeks do not mess up the encoding.
// But as shown below, the offset of the data CAN be incorporated.
inline char Encode(char c_) const
{ return (char) (c_ ^ _pos ^ 211); }
inline char Decode(char c_) const
{ return (char) (c_ ^ _pos ^ 211); }
long _pos;
};
int CEncryptStrategy::DataRead(void* lpBuf, int nCount)
{
int result = 0;
if (nCount > 0)
{
CTempBuffer buf (nCount);
char* dest = (char*) lpBuf;
result = c4_Strategy::DataRead(buf, nCount);
for (int i = 0; i < result; ++i)
{
dest[i] = Decode(buf[i]);
++_pos;
}
}
return result;
}
void CEncryptStrategy::DataWrite(const void* lpBuf, int nCount)
{
if (nCount > 0)
{
CTempBuffer buf (nCount);
const char* src = (const char*) lpBuf;
memcpy(buf, lpBuf, nCount);
for (int i = 0; i < nCount; ++i)
{
buf[i] = Encode(src[i]);
++_pos;
}
c4_Strategy::DataWrite(buf, nCount);
}
}
/////////////////////////////////////////////////////////////////////////////
int main()
{
// This property could just as well have been declared globally.
c4_StringProp pLine ("line");
{
// This is where the magic takes place.
CEncryptStrategy efile;
efile.DataOpen("secret.dat", true);
c4_Storage storage (efile);
static const char* message[] = {
"This is a small message which will be encrypted on file.",
"As a result, none of the other MetaKit utilities can read it.",
"Furthermore, a hex dump of this file will produce gibberish.",
"The encryption used here is ridiculously simple, however.",
"Beware of naive encryption schemes, cracking them is a sport.",
0
};
// Store the text lines as separate entries in the view.
c4_View vText;
for (const char** p = message; *p; ++p)
vText.Add(pLine [*p]);
storage.Store("text", vText);
storage.Commit();
}
// The end of the preceding block will flush out all data to file.
{
// Repeat the process when accessing the encrypted file again.
CEncryptStrategy efile;
efile.DataOpen("secret.dat", false);
c4_Storage storage (efile);
c4_View vText = storage.View("text");
for (int i = 0; i < vText.GetSize(); ++i)
{
c4_String s = pLine (vText[i]);
puts(s);
}
}
// At this point, an encrypted data file is left behind on the disk.
return 0;
}
/////////////////////////////////////////////////////////////////////////////